//when input is null/0 read step'value and do some thing
#include<cstdio>
#include<cstdlib>
#include"include/allinall_datatype.hpp"
#include"include/allinall_shader.hpp"
#include"include/allinall_object.hpp"
#include<typeinfo>

#include<map>
#include<vector>

#include<glad/glad.h>
#include<GLFW/glfw3.h>
#pragma comment(lib,"glfw3_mt")
#pragma comment(lib,"OpenGL32")

cameraclass camera;
glsl glsls;

typedef float mat[4][4];
typedef float vec3[3];

bool done=false;
unsigned char step=0;

template<class T>
void check(T signal){
	if(signal){++step;return;}
	char msg[256]{"Fail"};
	int temp=0;
	#define addmsg(m) if(!temp++)sprintf(msg,"%s %s\v",msg,#m)
	switch(step){
	case 1:
		glfwDestroyWindow((GLFWwindow*)signal);
		addmsg(create_window);
	case 0:
		glfwTerminate();
		addmsg(init_glfw);
	default:
		if(done)return;
		perror(msg);
		exit(-1);
	}
}
void LocalInit(){
	check(glfwInit());
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,5);
	glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_VISIBLE,GLFW_TRUE);
	glfwSwapInterval(1);
}
GLFWwindow*LocalCreateWindow(size_t width,size_t height,const char*title){
	GLFWwindow*win=glfwCreateWindow(width,height,title,NULL,NULL);
	check(win);
	glfwMakeContextCurrent(win);
	void key_callback(GLFWwindow*,int,int,int,int);
	glfwSetKeyCallback(win,key_callback);
	return win;
}
int main(){
	LocalInit();
	GLFWwindow*onewin=LocalCreateWindow(600,400,"base");
	gladLoadGL();

	glsl glsls{};
	glsls.addglsl("vtx.glsl",GL_VERTEX_SHADER);
	glsls.addglsl("frg.glsl",GL_FRAGMENT_SHADER);
	// glsls.listglsl('a');
	shader shader1{glsls,0,0};

	bufferobj vbos1{};
	// vbos1.listbuffers();
	vbos1.add("no.1",1);
	// vbos1.listbuffers();
	vbos1.bind("no.1",0);

	mesh a;
	float pos[9]{
		-0.5f,-0.5f,0.0f,
		0.5f,-0.5f,0.0f,
		0.0f,0.7f,0.0f
	};
	float clr[9]{
		0.0f,1.0f,0.0f,
		0.0f,0.0f,1.0f,
		1.0f,0.0f,0.0f
	};
	a.load("pos",9,3,pos);
	a.load("clr",9,3,clr);

	// float*data=(float*)(a.data);
	// for(int i=0;i<a.size/4;++i)
	// 	printf("%f\n",data[i]);

	vbos1.putdata(a.data,a.size);

	arrayobj vaos1{};
	vaos1.add("mesh.a",1);
	vaos1.bind("mesh.a",0);
	vaos1.setline(&a);

	shader1.use();
	// printf(">>>\n");
	// printf("%s:%s\n",shader1.glsltake[0],shader1.glsltake[1]);

	while(!glfwWindowShouldClose(onewin)){
		glfwWaitEvents();
		glClear(GL_COLOR_BUFFER_BIT);
		glDrawArrays(GL_TRIANGLES,0,3);
		glfwSwapBuffers(onewin);
	}

	done=true;
	check(0);
}
void key_callback(GLFWwindow*win,int key,int scancode,int action,int mode){
	if(action){
		printf("%d\n",key);
		switch(key){
			case GLFW_KEY_KP_8:
			break;
			case GLFW_KEY_KP_2:
			break;
			case GLFW_KEY_KP_4:
			break;
			case GLFW_KEY_KP_6:
			break;
		}
	}
}